﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;
using System.Xml;
using System.Xml.Linq;
using System.Text;
using System.Threading.Tasks;

namespace cogency.representation
{
    public class RDeclaration
    {
        public readonly string Name;
        public readonly string Comment;
        public readonly string ReferencedName;
        public readonly RDeclarationType DeclarationType;
        public readonly RDeclarationScope DeclarationScope;
        public readonly RBuiltinType BuiltinType;
        public readonly List<RDeclaration> Items;
        public readonly RDeclaration ReturnType;

        public bool HasItems
        {
            get
            {
                return (Items != null) && (Items.Count > 0);
            }
        }

        public RDeclaration(
            string name, 
            string comment, 
            RDeclarationType declarationType, 
            RDeclarationScope declarationScope = RDeclarationScope.Ignored, 
            RBuiltinType builtinType = RBuiltinType.Invalid,
            string referencedName = null,
            RDeclaration returnType = null,
            IEnumerable<RDeclaration> items = null)
        {
            Name = name;
            Comment = comment;
            DeclarationType = declarationType;
            DeclarationScope = declarationScope;
            BuiltinType = builtinType;
            ReferencedName = referencedName;
            ReturnType = returnType;
            if( items != null )
            {
                Items = new List<RDeclaration>();
                Items.AddRange(items);
            }
        }

        public XElement AsXElement()
        {
            XElement result = new XElement("declare");
           
            result.SetAttributeValue("name", Name);
            result.SetAttributeValue("type", DeclarationType);
            if (!string.IsNullOrEmpty(Comment))
            {
                result.Add(new XElement("comment", Comment));
            }
            result.SetAttributeValue("scope", DeclarationScope);

            if (BuiltinType != RBuiltinType.Invalid)
            {
                result.SetAttributeValue("ref-type", BuiltinType);
            }
            if (ReferencedName != null)
            {
                result.Add(new XElement("ref-name", ReferencedName));
            }
            if( ReturnType != null)
            {
                XElement returns = new XElement("returns");
                returns.Add(ReturnType.AsXElement());
                result.Add(returns);
            }
            
            if (Items != null)
            {
                XElement items = new XElement("items");
                foreach (RDeclaration decl in Items)
                {
                    items.Add(decl.AsXElement());
                }
                result.Add(items);
            }            
            return result;
        }

        public override string ToString()
        {
            return AsXElement().ToString();
        }
    }
}
